# 设计一款能实现多人聊天的系统：使用socket和多线程技术，编写全多人聊天室

import socketserver
import threading
import logging
import myutils

logging.basicConfig(level=logging.INFO)


class MyHandler(socketserver.BaseRequestHandler):
    # 客户端信息
    clients = {}

    def setup(self):
        self.event = threading.Event()

    def handle(self):
        # 接受到了数据，分发
        conn = self.request
        self.clients[self.client_address] = conn
        while not self.event.is_set():
            try:
                data = conn.recv(1024).decode().strip()
                #处理客户段主动断开的异常（非quit）
                if not data:
                    raise BrokenPipeError
            except Exception as e:
                logging.info(e)
                data = 'quit'

            logging.info(data)

            # 客户端通知，退出机制
            if data == 'quit':
                logging.info('quit!')
                break

            msg = 'ack {}\n'.format(data)

            for c in self.clients.values():
                c.send(msg.encode())


    def finish(self):
        super().finish()
        self.event.set()
        self.clients.pop(self.client_address)

ip = '127.0.0.1'
port = 8080
addr = (ip, port)
server = socketserver.ThreadingTCPServer(addr, MyHandler)
threading.Thread(target=server.serve_forever, name='myserver', daemon=True).start()  # 需等待客户端退出后，主线程才能正常结束


myutils.showthreads()

while True:
    cmd = input('>>>>').strip()
    if cmd == 'quit':
        server.shutdown()
        server.server_close()
        break
